Canigó - Servei de presentació de tags 2.1
SERVEI DE PRESENTACIÓ DE TAGS
IntroduccióPropòsitEl Servei de Tags té com a propòsit principal oferir un ventall de components a utilitzar dins de les nostres pàgines. En l'actualitat es basen en l'ús de pàgines JSP (Java Server Pages), per ser ara mateix la tecnologia de presentació més estesa. canigo, en el seu afany de proporcionar la màxima flexibilitat i facilitat als desenvolupadors ha seleccionat, estès i millorat algunes propostes de la comunitat. En molts dels components es fan servir tecnologies Web d'última generació i s'estenen solucions openSource ja existents. Tanmateix s'ha definit una política de configuració que facilita l'herència de valors de les propietats entre components, aspecte no assolible amb la tecnologia de tags JSP. En l'actualitat existeix una nova generació de desenvolupament Web anomenada AJAX 1(Asynchronous JavaScript And XML). Tot i que el desenvolupador no necessita del coneixement d'aquest tecnologia, canigo s'ha adaptat a aquesta nova generació en la implementació interna dels seus tags. Es considera prerequisit per a la lectura d'aquest document el coneixement en HTML, CSS i l'ús de Struts. Context i Escenaris d'ÚsEl Servei de Tags es troba dins dels serveis de Presentació de canigo. Per a la utilització dels tags de canigo es requereix d'un entorn basat en les següents tecnologies:
Versions i DependènciesEn el present apartat es mostren quines són les versions i dependències necessàries per fer ús del Servei. VersionsNovetats en versió 1.1.
Dependències bàsiquesLes dependències descrites a la següent url son requerides per tal de fer funcionar el servei: A qui va dirigitAquest document va dirigit als següents perfils:
Documents i Fonts de referència
GlossariTLD (Tag Library Descriptor) Un TLD és un fitxer en format XML que permet a un desenvolupador definir un conjunt de tags. Per cada tag es poden descriure els seus atributs i la classe associada que generarà el contingut de sortida a la pàgina en la que es faci servir. Tot i que l'ús de tags específics permet eliminar l'ús de codi Java des de les nostres pàgines JSP, no eliminen la necessitat de crear codi Java. S'han de crear igualment classes Java que facin el treball del tag. Aquestes classes han de estendre les classes definides al package 'tagext' de J2EE. Descripció DetalladaArquitectura i ComponentsL'arquitectura del Servei de Tags és basa en l'ús de llibreries de tags JSP. Es recomana una lectura prèvia de la url 'http://java.sun.com/products/jsp/tutorial/TagLibrariesTOC.html' per conèixer què és una llibreria de tags, com es creen i com s'utilitzen. A mode de resum, l'arquitectura que hi ha al darrera de les llibreries de tags és la mostrada a continuació:
Seguint la filosofia d'independència màxima de la implementació canigo defineix interfícies per tots els tags. En l'actualitat s'ofereixen implementacions basades en JSP i Struts. Degut a la filosofia que permet configurar de forma externa els tags de les pàgines, la migració a altra tecnologia serà molt més fàcil.
Arquitectura de Procediment d'Inicialització InternLa configuració dels tags es realitza mitjançant el Servei de Configuració com si de classes planes es tractessin. El model inherent a JSP, pel qual és el contenidor qui instancia els tags no ens permet de fer ús directe del patró 'Dependency Injection'. En qualsevol cas, es fa ús dels mecanismes definits pel Servei de Configuració per a inicialitzar els tags. El procediment seguit per a la inicialització d'un tag és el següent:
Imaginem que a la pàgina JSP tenim un component definit de la següent forma:
<fwk:text styleId="firstname" property="firstname"/> És obligatori que definim aquestes 2 propietats a les nostres pàgines. L'atribut 'property' és equivalent al que fa servir Struts, que ens permet lligar quin atribut de l'objecte volem presentar. L'atribut 'styleId' servirà per obtenir la configuració del tag des del fitxer de configuració. El propi tag, dins el seu mètode d'inicialització crida a la classe 'TagUtil' indicant-li quin és el seu 'styleId' per obtenir les seves propietats.
<property name="tagsConfiguration"> <map> <entry key="*" "> <list> ... <bean id="..." class="..."> <property name="styleId" value="nombreEstiloId" "/> </bean> </list> </entry> <entry key="reqCode"> <list> <bean ...> <property name="styleId" value="nombreEstiloId"/> </bean> </list> </entry> </map> Segons el reqCode que arribi com a paràmetre a la url '...?reqCode=...' s'escollirà una entry o una altra per configurar els tags de la pàgina. L'estil indicat lliga amb l'atribut 'styleId' que s'ha definit a la pàgina JSP
Interfícies i Components GenèricsEs pot trobar tota la documentació JavaDoc y el codi font referent aquests components a les següents urls: JavaDoc: http://canigo.ctti.gencat.net/confluence/canigodocs/site/canigo2_0/canigo-services-web/apidocs/index.html Instal- lació i ConfiguracióPrerequisit: Per al correcte funcionament d'aquest servei és important que prèviament s'hagin realitzat les configuracions especificades a l'apartat 'Configuració Bàsica' del document 'Serveis de Presentació'. Instal- lacióPer a la instal- lació del Servei de Tags es requereix de l'ús del fitxer 'canigo-services-web.jar' i les dependències indicades a l'apartat 'Versions i Dependències'. Configuració GeneralA diferència del tradicional mecanisme de tags JSP en el que dins la pàgina s'especifiquen les propietats del tag, canigo va més enllà i permet tractar els tags com classes Java normals, a fi que es puguin injectar les seves propietats mitjançant el Servei de Configuració. Aquesta aplicació es fa només pels components d'entrada de formularis, degut a la necessitat que tenen diferenciada segons l'acció realitzada. canigo fa ús del Servei de Configuració per a definir els diferents comportaments d'una mateixa plana de presentació segons el cas d'ús. Això implica que una mateixa plana JSP pot tenir diferents configuracions de visualització i comportament dinàmic, descrites de manera declarativa. Les nostres pàgines JSP seran molt simples, ja que s'externalitzaran les seves propietats en aquests fitxers de configuració, en els quals podem utilitzar la potència de l'herència per definir propietats comuns. Per cada acció Struts configurada al fitxer 'action-servlet.xml' definirem la propietat 'tagsConfiguration' on definirem el següent format: La configuració del Servei de Tags implica els següents passos:
Definició de la configuració per l'acció La definició de les propietats que s'usaran pels tags d'una pantalla es poden definir per cada acció de l'aplicació. Així, per exemple podríem representar en una creació alguns aspectes de forma diferent.
Si es defineix amb el valor '*' es considerà com la configuració per defecte, en tant que s'aplicarà en els següents casos:
Exemple:
<bean name="/accounts"" class="net.gencat.ctti.canigo.samples.jpetstore.struts.action.AccountAction"> ... <property name="tagsConfiguration""> <map> <entry key="*""> <list> <bean id="idForm" ...> <property name="styleId" value="actionForm"/> </bean> <bean id="idFirstName" ...> <property name="styleId" value="firstname"/> <property name="accesskey" value="forms.accountForm.field.firstname.accesskey"/> <property name="key" value="forms.accountForm.field.firstname"/> ... </bean> <entry key="edit""> <list> <bean id="idFirstName" parent="textFieldTag"> <property name="styleId" value="name"/> </bean> </list> </entry> </map> </property> </bean> >>Acció de Struts amb injecció de les seves propietats (veure document 'Serveis de Presentació' per a més referència). ddDefinició de la propietat 'tagsConfiguration' DDPer qualsevol reqCode es farà servir la configuració dels tags aquí indicada En cas que arribés el paràmetre 'reqCode' amb valor 'edit' es farà servir aquesta configuració Una vegada definida la propietat de configuració de l'acció podem definir les propietats de cadascun dels tags. Definició de les propietats d'un tag
<bean name="/action" class="....XXXAction"> ... <property name="tagsConfiguration"> <map> <entry key="*"> <list> <bean id="" class=""> ... </bean> La configuració d'un tag és equivalent a la configuració de qualsevol altre element (consultar el document 'Servei de Configuració' per més referència). A l'atribut 'class' doncs s'especificarà quin és la classe concreta d'implementació del tag que farem servir. En el cas de Struts farem ús de les següents classes:
En tots ells és necessari configurar les següents propietats:
Addicionalment, depenent del tag podrem configurar altres propietats. Tots ells permeten configurar les propietats dels tags en el que es basen. Podem per tant configurar qualsevol dels atributs de Struts mitjançant el fitxer de configuració. La potència real d'aquesta forma de treballar versus els clàssics tags JSP és que podem usar l'herència i definir propietats genèriques a un grup de tags. Així, podem definir propietats comunes a varis tags mitjançant el Servei de Configuració tal i com es mostra en el següent exemple:
<!-- TAG's default configuration --> <bean id="formTag" class="net.gencat.ctti.canigo.services.web.struts.taglib.forms.FormTag"/> <bean id="actionImageTag" class="net.gencat.ctti.canigo.services.web.struts.taglib.forms. ActionImageTag"/> <bean id="submitTag" class="net.gencat.ctti.canigo.services.web.struts.taglib.forms.SubmitTag"/> <bean id="textFieldTag" class="net.gencat.ctti.canigo.services.web.struts.taglib.forms.fields. TextFieldTag"> <property name="i18nService" ref="i18nService"/> <property name="validationService" ref="webValidationService"/> <property name="layout" value="true"/> </bean> ... <bean id="checkboxFieldTag" class="net.gencat.ctti.canigo.services.web.struts.taglib.forms. fields.CheckboxFieldTag"> <property name="i18nService" ref="i18nService"/> <property name="validationService" ref="webValidationService"/> <property name="layout" value="true"/> </bean> En aquest exemple, es defineixen les propietats comunes als diferents tipus de components. Així podem fer ús de l'herència per definir els components específics de la nostra aplicació com per exemple: <bean parent="textFieldTag"> <property name="styleId" value="id"/> <property name="mode" value="E,I,I"/> <property name="key" value="forms.accountForm.field.id"/> </bean> Aquí s'ha eliminat la necessitat de definir el id del tag i s'ha fet ús de l'herència mitjançant el tag 'textFieldTag' que fa referència al '<bean id="textFieldTag">' que s'ha definit en el fitxer extern. Podem, per últim, estructurar la següent forma el nostre fitxer de l'aplicació:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!- TAG's default configuration -> <bean id="formTag" class="net.gencat.ctti.canigo.services.web.taglib.config.FormTagConfiguration"/> <bean id="fieldTag"> ... </bean> <bean id="textFieldTag" class="net.gencat.ctti.canigo.services.web.taglib.config. TextFieldTagConfiguration" parent="fieldTag"> </bean> <import resource="action-servlet-accounts.xml"/> <import resource="action-servlet-categories.xml"/> <import resource="action-servlet-products.xml"/> <import resource="action-servlet-items.xml"/> </beans> On mitjançant el tag 'import' es fa referència a diferents fitxers de configuració (grups per acció, per una sola acció, etc.) A continuació s'ofereix explicació de la configuració de cadascun dels tags. Configuració del Tag 'ConfigurationTag'Ús: Obligatori, doncs genera les llibreries dels components El tag Configuration de canigo s'encarrega de generar totes les llibreries necessàries que requereixen els tags. Per a generar les llibreries necessàries accedeix al fitxer de propietats de Spring i per cada tag definit obté les seves propietats. Segons els valors d'aquestes propietats genera les llibreries. Per exemple, en el cas de especificar 'showCalendar' a un TextField, generarà les llibreries de calendari, així com la llibreria de literals de calendari de l'idioma de l'usuari entre d'altres. Atributs:
Propietats:
Exemple:
<bean id="configurationTag" class="net.gencat.ctti.canigo.services.web.struts.taglib. configuration.ConfigurationTag"> <property name="styleId" value="defaultConfiguration"/> <property name="i18nService" ref="i18nService"/> </bean> I a la pàgina JSP (es recomana definir-lo al template de Struts Layout): <fwk:configuration styleId="defaultConfiguration" />
Configuració dels tags de FormulariConfiguració del Tag Form Aquest tag es basa en Struts, pel que sempre podem definir les propietats que el tag 'form' de Struts proporciona. En aquest apartat només es definiran aquelles propietats addicionals que ofereix canigo.
<fwk:form action="accounts.do" reqCode="edit" width="500" method="post"> Atributs addicionals:
Dins el tag <props> podem definir les següents propietats:
Exemple segons validationType 'SERVER':
<property name="validationProperties"> <props> <prop key="validationType">SERVER</prop> </props> </property> ![]() Exemple segons validationType 'CLIENT': <bean parent="formTag"> <property name="styleId" value="actionForm"/> <property name="validationProperties"> <props> <prop key="validationType">CLIENT</prop> <prop key="validatorName">account</prop> </props> ... </bean> ![]() Configuració de Propietats comunes a tots els tags d'entrada de dades en formulari Quan desenvolupem una aplicació en la que intervenen formularis que es poden mostrar de manera diferenciada segons els privilegis de l'usuari o l'acció escollida existeixen 2 formes tradicionals de definir-los:
Tant una com l'altra solució requereixen d'un esforç massa gran. En la primera opció, un canvi que impliqui afegir un camp o retocar un ja existent pot requerir de la necessitat de modificar vàries pàgines JSP, mentre que en la segona solució la pàgina es fa molt difícil de llegir i mantenir. canigo permet l'ús de modes de formulari que s'aplicaran als components continguts en ell. Segons el mode especificat, els components es mostraran d'una o un altra forma (ocults, editables, no editables, etc.) Els tags input de canigo es basen en els tags proporcionats per Struts, de forma que podem sempre definir les seves propietats als nostres fitxers de configuració. En aquest apartat només es mostren les propietats addicionals que ofereix canigo:
En tota aplicació Web tenim que utilitzar formularis. Aquests solen estar estructurats mitjançant una graella en la que es mostren els components de formulari (camps d'entrada de dades, de selecció, botons d'opció, etc.) i a l'esquerra una etiqueta associada al camp. Mitjançant Struts, JSTL i l'ús del tag '<label>' (descuidat per molts desenvolupadors però existent a l'estàndard HTML fa molt de temps) la realització d'un component implicaria el següent codi:
<tr><td> <label for="id" ...> <fmt:message key="key.id "/> </label> <html:text property="id" size="20" maxlength="20"/> </td></tr> Resulta obvi que a mesura que anem afegint components a la nostra pàgina JSP aquesta es fa feixuga de llegir, ja que incorpora gran quantitat de layout i etiquetes. Per què no un tag que generi tot aquest codi i fos senzill d'utilitzar? Amb el nou tag proporcionat per canigo el codi equivalent seria: <fwk:text styleId="id" property="id"/> Exemple: <bean parent="textFieldTag"> <property name="styleId" value="firstname"/> ... <property name="key" value="forms.accountForm.field.firstname"/>
Per a poder accedir mitjançant el teclat a qualsevol camp, podem usar l'atribut 'accesskey'. Mitjançant HTML podríem crear el següent codi:
<label for="nombre"><u>N</u>ombre</label> <input type="text" accesskey="n" id="nombre" name="nombre"> Mode tradicional canigo genera de forma automàtica 2 el codi d'accés als components. En conjunció amb el servei de internacionalització defineix quina és la clau que defineix quin és el caràcter a subratllar. Exemple:
<bean parent="textFieldTag"> <property name="styleId" value="firstname"/> <property name="accesskey" value="forms.accountForm.field.firstname.accesskey"/>
El mode dels camps permet especificar si un camp "input" ha de ser editable, de lectura, ocult o que no aparegui en el formulari segons el mode de display del formulari. Això permet per exemple que un camp que forma part de la clau primària només sigui editable durant la creació, o mostrar camps calculats només quan es visualitza la informació i no quan s'edita. El comportament per defecte és que els camps es mostrin editables si el mode del formulari es CREATE o EDIT, i es mostrin de lectura (valor text pla sense component HTML i un hidden amb el valor del camp) si el mode del formulari és INSPECT. Aquest comportament per defecte pot alterar-se en els camps mitjançant l'atribut 'mode'. El valor que s'ha d'assignar a aquest atribut ha de seguir el patró 'X,Y,Z'; on X és el comportament que tindrà el camp en cas que el mode del formulari sigui 'FormUtils.CREATE_MODE', Y el comportament en el mode edició ('FormUtils.EDIT_MODE') i Z en mode de consulta ('FormUtils.INSPECT_MODE'). Els valors possibles per X,Y i Z són:
Una vegada especificat en quin mode funcionarà el formulari, els components apareixeran segons el mode especificat, sense que per això s'hagi de generar codi JSP addicional.
Es pot especificar que es mostri una imatge o text al principi de l'etiqueta per indicar que un camp és requerit si especifiquem el valor 'true' per la propietat 'required'. Aquesta propietat no és necessària especificar-la si en el Servei de Validació s'ha configurat que el camp és obligatori. El tag accedeix al servei i pregunta si el camp associat és requerit. Per a que això funcioni cal que s'especifiqui la propietat 'validationService' al tag. El comportament proporcionat per canigo crea el contingut ' Podem configurar l'estil de l'asterisc modificant al fitxer d'estils la següent entrada:
label span.required \{ color: #c32; \} ![]()
Aquestes 3 propietats ens permeten especificar l'ajuda contextual als camps.
Per a ser utilitzat el tag 'Configuration' importa el fitxer js 'scrips/ajax/ajaxtags/canigo- ajaxtags.js'. Si es vol canviar el comportament per defecte es poden fer els canvis necessaris a aquest fitxer. En aquest codi es genera de forma automàtica el link que mostrarà el tooltip en passar per sobre. Addicionalment podem configurar els estils dels tooltips segons la definició dels estils mostrats a continuació:
a.tooltip:link \{text-decoration: none; \} a.tooltip:visited \{text-decoration: none; \} a.tooltip:hover \{text-decoration: none; cursor:help; \} a.tooltip:active \{\} Un dels estils més útils és 'cursor:help' dins a hover, ja que ens apareixerà el cursor d'ajuda quan passem per sobre de l'etiqueta del component.
Configuració del Tag Text El tag de text permet l'entrada de dades i es basa en el tag de Struts. Per tant, totes les propietats definides a Struts permeten ser definides a canigo. A més de les propietats pròpies als components de formulari i de les de Struts s'han incorporat les següents propietats:
Per a que el calendari es mostri correctament cal:
Els literals del calendari es troben definits en fitxers '.js' que es troben al directori 'scripts/calendars/dynarch/lang/'. El tag 'Configuration' és qui s'encarrega d'afegir la referència al fitxer corresponent a l'idioma de l'usuari. Integració amb el Servei de Validació Per a que s'usi un format de data específic, canigo consulta per la propietat associada al tag (indicada mitjançant l'atribut 'property' del tag) si es tracta d'un objecte de tipus 'java.util.Date'. Si és així, obté el format que s'ha d'aplicar segons l'idioma de l'usuari. Podem configurar quin serà el format de data utilitzat per cada llenguatge definit una nova clau i el seu patró en la propietat 'localeDatePatternsMap' del fitxer 'property-editors.xml' tal i com es mostra a continuació:
... <bean id="customEditors" class="java.util.HashMap"> <constructor-arg> <map> <entry key="java.util.Date"> <bean class="net.gencat.ctti.canigo.services.i18n.spring.beans.propertyeditors.CustomDateEditor"> <property name="i18nService" ref="i18nService"/> <property name="localeDatePatternsMap"> <map> <entry> <key><value>es</value></key> <value>dd/MM/yyyy</value> </entry> <entry> <key><value>en</value></key> <value>MM/dd/yyyy</value> </entry> </map> </property> ... </bean> Configuració del Tag 'Password' El tag de password permet definir les mateixes propietats que el tag 'Text'. Exemple:
<bean parent="passwordFieldTag"> <property name="mode" value="E,I,I"/> <property name="styleId" value="password"/> <property name="key" value="forms.accountForm.field.password"/> </bean> Configuració del Tag 'TextArea'
Permet especificar la generació d'un textarea en el que es permetin justificats, formats, colors, etc. El contingut aquí introduït serà enviat com HTML. Per especificar els decoratorProperties usarem els següents valors:
Exemple:
<bean parent="textAreaFieldTag"> <property name="styleId" value="comments"/> <property name="key" value="forms.accountForm.field.comments"/> <property name="rows" value="10"/> <property name="cols" value="40"/> <property name="decoratorProperties"> <map> <entry> <key><value>theme</value></key> <value>advanced</value> </entry> <entry> <key><value>mode</value></key> <value>exact</value> </entry> </map> </property> </bean> Mitjançant l'exemple a dalt mostrat tindríem un component com el mostrat a continuació: Configuració del Tag 'Select' Permet definir les mateixes propietats que les definides per Struts i les propietats generals a tots els tags d'entrada de formulari definides anteriorment. Addicionalment es proporcionen 2 funcionalitats prou importants:
Si volem mostrar una llista d'opcions que prové d'una base de dades canigo canigo ofereix la possibilitat de definir la font de les dades. Per això cal que seguim els següents passos:
El seu ús és equivalent al definit pel Servei de Llistats.
En la propietat 'config.adapters' definirem les diferents queries a executar per a recuperar les llistes. Aquestes queries es troben definides en HQL, pel que obtenim objectes.
<bean id="selectFieldTag" class="net.gencat.ctti.canigo.services.web.struts.taglib. forms.fields.SelectFieldTag"> ... <property name="optionsListService" ref="optionsListService"/> ... <bean parent="selectFieldTag"> <property name="key" value="forms.accountForm.field.preferredCategory"/> <property name="styleId" value="preferredCategoryId"/> <property name="optionsListName" value="categoriesList"/> </bean>
En cas de voler presentar la llista d'opcions d'un select segons la selecció realitzada a un altra selecció, definirem a més del definit en la secció anterior un nou atribut 'selectFieldSource' en el que definirem:
Per exemple, imaginem que volem mostrar la llista d'animals segons la categoria escollida. <entry key="animalsList"> <bean parent="defaultOptionBaseHibernateAdapter"> <property name="hql"> <value> FROM net.gencat.ctti.canigo.samples.jpetstore.model.Product AS vo WHERE 1=1 /~category: AND vo.category.id LIKE \{category\} ~/ /sortColumn: ORDER BY vo.[sortColumn] [sortDirection]/ </value> </property> </bean> </entry> En aquesta hql apareix el paràmetre {category} dins el LIKE que és el que ens permetrà lligar que se'ns retornin els productes amb la categoria indicada. Per a que s'envii com a criteri valor dins {category} el valor escollit a la select source definirem com a 'paramName' el valor 'category'.
<bean parent="selectFieldTag"> <property name="key" value="forms.accountForm.field.preferredAnimal"/> <property name="styleId" value="preferredAnimalId"/> <property name="optionsListName" value="animalsList"/> <property name="selectFieldSource"> <map> <entry> <key><value>source</value></key> <value>preferredCategoryId</value> </entry> <entry> <key><value>paramName</value></key> <value>category</value> </entry> </map> </property> </bean> Configuració del Tag 'Checkbox' Permet definir les mateixes propietats que les definides per Struts i les propietats generals a tots els tags d'entrada de formulari definides anteriorment. Exemple:
<bean id="checkboxFieldTag" class="net.gencat.ctti.canigo.services.web.struts. taglib.forms.fields.CheckboxFieldTag"> <property name="i18nService" ref="i18nService"/> <property name="validationService" ref="webValidationService"/> <property name="layout" value="true"/> </bean> <bean parent="checkboxFieldTag"> <property name="styleId" value="lower18"/> <property name="key" value="forms. accountForm.field.lower18"/> </bean> Configuració del Tag 'File' Aquest tag permet especificar l'ús d'un fitxer de upload Veure 'Servei de Upload de Fitxers' per a més referència de la configuració necessària. El tag requereix que es configuri la propietat 'encType' del tag 'Form' amb el següent valor: "multipart/form-data" Exemple:
<bean parent="fileFieldTag"> <property name="styleId" value="file"/> <property name="mode" value="E,I,I"/> <property name="key" value="forms.fileForm.field.file"/> </bean> Configuració dels tags de LlistatsVeure document 'Servei de Llistats'. Configuració dels tags en el JSPEl nou servei de configuració permet definir totes les propietats de text o referències de components en el JSP. Això fa que no sigui necessari tenir definit un styleId que faci referència en el action-services-XXX.xml en la propietats tagsConfiguration de l'action. Cal remarcar que per propietats complexes, com Maps o Lists, no es dona suport i necessàriament s'han d'escriure en els fitxers d'Spring i relacionar-les amb el styelId. Aquesta utilitat simplifica el desenvolupament ja que es pot tenir configurat totes les dades del tag en el propi JSP sense necessitat d'haver d'escriure les propietats en fitxers Spring. Per fer referències a components dins el tag JSP s'ha creat l'atribut services en tots el tags que permet especificar la propietat i la referència del component que se li ha d'injectar al tag. Seguidament es mostra un exemple. <fwk:text styleId="password" layout="false" property="password" En l'exemple anterior s'estan injectant els beans d'spring amb id 'i18nService' i 'webValidationService' en les propietats 'i18nService' i 'validationService' del tag, respectivament. Tags avançatsAquests tags hi són a partir de la versió 1.1. Dirty Form WarningEl dirty form warning és una funcionalitat que permet a l'usuari avisar quan es córrer el risc de perdre els canvis en un formulari. Quan es clicka un link i produeix una descàrrega del formulari que té canvis, surt un missatge d'avís de pèrdua de les dades. Llavors l'usuari pot decidir que es procedeixi a la descàrrega del formulari per presentar una nova pàgina o decidir aturar l'acció per no perdre les dades. L'event que s'escolta per llençar l'avís és el onBeforeUnload suportat per Internet Explorer 6 i FireFox 1.5. El tag que dona aquesta funcionalitat és el dirtyFormWarning Dependències: ajaxtags-1.1.jar
Exemple d'ús: <fwk: DirtyFormWarning source="actionForm" messageKey="errors.lostChanges" /> Search PanelEl panell de cerca és una utilitat que permet a l'usuari poder trobar el valor adient d'un camp. El panell de cerca permet mostrar de les dades que compleixen la condició més dades relacionades. Per exemple si s'estan buscant cognoms de persones, el panell de cerca permet mostrar a part del cognom, el nom, el càrrec que ocupa, centre, etc per tal d'ajudar a l'usuari a escollir correctament i en cas de repetició, poder discriminar. Aquesta és la gran diferència amb l'autocomplete o els selects, que només mostren un dada en concret. Les cerques es poden fer tantes com es vulguin, però un cop es seleccioni una dada, el panell s'amagarà. Si es torna a pitjar el botó de cercar, el panell de cerca tornarà a aparèixer amb les dades de la última cerca. El tag que ofereix aquesta funcionalitat és el searchPanel Dependències: ajaxtags-1.1.jar
Identificador del div que conté el panell de cerques. Va bé per poder definir estils .
Nom de la query a executar. Ha d'estar definida en canigo-services-weblist.xml.
Nom del paràmetre de la query que se li associarà el valor del camp entrat a buscar.
Llista de propietats del bean que retorna la query. Es permeten propietats relacionades. Per exemple si la query retorna elements R i aquests tenen un relació L que conté elements C, es pot posar L.id, que seria el id de l'element C associat.
Nom de la propietat del bean que retorna la query que es vol copiar al camp de text target.
Claus de multillenguatge pel nom de les columnes de la taula de resultats. El nombre de columnLabels i de tableProperties ha de ser igual. En cas de no ser-ho el searchPanel avisa del conflicte.
Nom de mètode javascript que sap fer el pintat del resultats. Aquest paràmetre permet a l'usuari canviar l'aspecte de la presentació de resultats. Aquesta funció ha conèixer el format json que retorna servidor per poder presentar les dades. Exemple:canigo-services-web-list.xml
<bean name="valueListHandler" class="net.mlw.vlh.DefaultValueListHandlerImpl"> <property name="config.adapters"> <map> <entry key="accountList"> <bean parent="baseHibernateAdapter"> <property name="hql"> <value> FROM net.gencat.ctti.canigo.samples.jpetstore.model.Account AS vo WHERE 1=1 /~firstname: AND vo.firstname LIKE \{firstname\} ~/ /~lastname: AND vo.lastname LIKE \{lastname\} ~/ /sortColumn: ORDER BY vo.[sortColumn] [sortDirection]/ </value> </property> </bean> </entry> </map> </property> </bean> JSP: <input type="button" value="search" id="searchPanelButton" /> <fwk:searchPanel styleId="searchPanel" source="searchPanelButton" target="city" popupId="searchPanelDiv" optionsListName="accountList" tableProperties="firstname,lastname,city" selectedProperty="city" columnLabels="name.label,lastname.label,city.label" indicator="indicator" queryParameter="firstname" /> Per fer servir el searchPanel s'han d'importar els següents scripts: <!-- Search panel --> <script src="/canigo-samples-jPetstore/scripts/ajax/ajaxtags/canigo-ajaxtags-searchPanel.js" type="text/javascript"> </script> <script type='text/javascript' src='/canigo-samples-jPetstore/AppJava/dwr/interface/searchPanelService.js'></script> ![]() AutocompleteL'autocomplete permet a l'usuari mostrar una llista de suggeriments pel valor que ha escrit. En el framework aquesta funcionalitat s'obté amb el tag autocomplete. Aquest autocomplete és importat de la llibreria ajaxtags 1.1 i s'ha adaptat perquè cridi al servei de cerques del framework i mostri correctament el resultat. Entre el servidor i client viatja una cadena json. Dependències: ajaxtags-1.1.jar
Component gràfic que es vol escoltar els events de teclat per tal de mostrar un autocomplete.
Camp de text que es desitja copiar el valor seleccionat en l'autocomplete. Normalment serà igual que el source.
Consulta definida en canigo-services-web-options-list.xml
Nombre de caràcters mínims en el camp de text origen per tal de disparar la consulta.
Funció a executar en cas d'error de dades o de comunicació.
Funció a executar en cas d'element buit.
Funció a executar després de presentar les dades. Exemple: canigo-services-web-options-list.xml
<bean name="defaultOptionValueListHandler" class="net.mlw.vlh.DefaultValueListHandlerImpl"> <property name="config.adapters"> <map> <entry key="animalsList"> <bean parent="defaultOptionBaseHibernateAdapter"> <property name="hql"> <value> FROM net.gencat.ctti.canigo.samples.jpetstore.model.Product AS vo WHERE 1=1 /~name: AND vo.name LIKE \{name\} ~/ /~category: AND vo.category.id LIKE \{category\} ~/ /sortColumn: ORDER BY vo.[sortColumn] [sortDirection]/ </value> </property> </bean> </entry> </map> </property> </bean> <bean id="animalsOptionListSource" parent="defaultOptionListSource"> <property name="optionListName" value="animalsList"/> <property name="optionLabelName" value="name"/> <property name="optionLabelProperty" value="id"/> </bean> <bean id="optionsListService" class="net.gencat.ctti.canigo.services.web.taglib. util.options.OptionsListServiceBase"> <property name="optionsListSources"> <map> <entry key="animalsList"><ref bean="animalsOptionListSource"/></entry> </map> </property> </bean> JSP: <fwk:text styleId="preferredProduct2.id" styleClass="fieldtext" property="preferredProduct2.id" /> <fwk:autocomplete source="preferredProduct2.id" target="preferredProduct2.id" parameters="preferredProduct2.id" className="autocomplete" minimumCharacters="1" indicator="indicator" optionsListName="animalsList" /> ![]() Botons amb imatgesEl tag fwk:button permet definir botons amb el contingut que és vulgui, entre d'altres per exemple amb taules, imatges, text, etc. Aquest tag és basat amb l'element d'html button, que és nou en l'html 4.0.
Events: onblur,onchange,onclick,ondbclick,onfocus,onkeydown,onkeypress,onkeyup,onmousedown,onmousemove,onmouseout, onmouseover,onmouseup Exemple:
<fwk:button styleId="desa" type="submit"> <img src="<c:url value="/images/save.jpg"/>" /> <fmt:message key="jsp.includes.submit" /> </fwk:button> ![]() Tag Swap SelectAquest component ofereix un tag que permeten moure o copiar elements entre dos selects múltiples. El seu ús es ben senzill. Dependències: ajaxtags-1.1.jar
Component gràfic que se li associa a l'event de onClick l'acció configurada. Normalment serà un botó.
La acció pot ser moure o copiar elements d'un select cap a un altre. Els possibles valors són COPY o MOVE.
Dades del select origen. Poden ser les dades seleccionades o totes. Els dos possibles valors són ALL o SELECTED
Select origen de dades.
Select destí de dades. Exemple:
<!-- Selects --> <fwk:select styleId="allAnimals" roperty="allAnimals" multiple="true" styleClass="multipleSelect" /> <fwk:select styleId="hateAnimals" property="hateAnimals" multiple="true" styleClass="multipleSelect" /> <!-- Botons --> <input type="button" id="moveAllRight" value=">>" lass="botonsswap" /> <input type="button" id="moveRight" value=">" class="botonsswap" /> <input type="button" id="moveLeft" value="<" class="botonsswap" /> <input type="button" id="moveAllLeft" value="<<" class="botonsswap" /> <! -- decoradors de swap --> <fwk:swapTag source="moveAllRight" scope="ALL" action="MOVE" fromSelect="allAnimals" toSelect="hateAnimals" /> <fwk:swapTag source="moveRight" scope="SELECTED" action="MOVE" fromSelect="allAnimals" toSelect="hateAnimals" /> <fwk:swapTag source="moveAllLeft" scope="ALL" action="MOVE" fromSelect="hateAnimals" toSelect="allAnimals" /> <fwk:swapTag source="moveLeft" scope="SELECTED" action="MOVE" fromSelect="hateAnimals" toSelect="allAnimals" /> L'exemple és la construcció de dos selects, amb quatre botons que permeten: - moveAllRight: mou totes les dades del select allAnimals al hateAnimals. - moveRight: mou les dades seleccionades del select allAnimals al hateAnimals. - moveAllLeft: mou totes les dades del select hateAnimals al allAnimals. - moveLeft: mou les dades seleccionades del select hateAnimals al allAnimals. PestanyesAquest component està compost per dos tags que permeten la construcció de pestanyes (Tabs). Dependències: ajaxtags-1.1.jar Els tags són els següents: TabPanelTagEl tag TabPanelTag és el tag pare que s'encarrega de crear les pestanyes i divs ocults, on es guardarà el contingut de les pàgines de les diferents pestanyes. En el cos d'aquest tag és on definirem totes les pestanyes (TabPageTag). Les propietats d'aquest tag són les següents:
Aquesta propietat defineix l'id del panell pare contenidor dels divs de les pestanyes. Amb aquest id podrem canviar l'estil general dels tabs.
Part comú de l'id dels divs de les pestanyes. El tag pare crearà cada div amb un id diferent. Aquest id es formarà amb la propietat 'contentStyleId' + '_tab' + index. Aquest índex ve donat pel número de pestanya dins del tag pare (TabPanelTag).
Aquesta propietat defineix l'id del la pestanya que està activa (la seleccionada). Amb aquest id podrem definir l'estil de la pestanya activa. Exemple:
<fwk:tabPanel panelStyleId="pestanas" contentStyleId="tabContent" currentStyleId="active"> TabPageTagEl tag TabPageTag defineix una pàgina de les pestanyes. Aquest tag no té sentit si no es troba dins d'un tag TabPanelTag. Les propietats d'aquest tag són les següents:
Si el valor es 'false', la pestanya quedarà desactivada (disabled) i no es podrà seleccionar.
Id del div on es troba el contingut de la pestanya. Això s'utilitza quan el contingut de la pestanya no es vol posar dins del cos (body) del tag de la pestanya (TabPageTag), sinó que es vol usar el contingut d'un altre div.
Si el valor es 'true', la pestanya quedarà activada al carregar la pàgina. Només es pot definir una pestanya com a 'defaultTab'.
Afegeix una imatge a la pestanya. Indica la ruta de la imatge que volem afegir. Per defecte posa la imatge a l'esquerra del títol(caption o captionKey) de la pestanya.
Indica la posició de la imatge. Els possibles valors són:
Només per pestanyes carregades mitjançant servidor. Indica la url on trobem el contingut de la pestanya. Aquesta url ha de retornar una jsp, que serà el contingut. Exemple pestanya client:
<fwk:tab captionKey="tabs.account.pestanya2"styleClass="contingut_tab" linkStyleClass="pestanya2" imageCaption="/canigo-samples-jPetstore/images/ast.gif" imagePosition="right"> Exemple pestanya servidor: <fwk:tab captionKey="tabs.account.server" styleClass="contingut_tab" linkStyleClass="pestanya4" baseUrl="accountList.do?reqCode=addRowEditList"/> Exemple complet: <fwk:tabPanel panelStyleId="pestanas" contentStyleId="tabContent" currentStyleId="active"> <fwk:tab captionKey="tabs.account.pestanya1" defaultTab="true" styleClass="contingut_tab" linkStyleClass="pestanya1" imageCaption="/canigo-samples-jPetstore/images/asc.gif"> <fwk:text styleId="firstname" styleClass="fieldtext" property="firstname"> </fwk:tab> <fwk:tab captionKey="tabs.account.pestanya2" styleClass="contingut_tab" linkStyleClass="pestanya2" imageCaption="/ canigo-samples-jPetstore/images/ast.gif" imagePosition="right"> <fwk:text styleId="country" property="country"> </fwk:tab> <fwk:tab captionKey="tabs.account.server" styleClass="contingut_tab" linkStyleClass="pestanya4" baseUrl="accountList.do? reqCode=addRowEditList"/> </fwk:tabPanel> ![]() GridBagLayoutEl tag de GridBagLayout és un component que permet la creació de taules que ofereixen un fàcil control de les propietats dels elements que continguin. Mitjançant la definició d'aquest Tag podrem controlar les propietats de cada cel- la (TD) individualment o conjuntament (amb les propietats de cada línia -TR- o de tota la taula -TABLE-). Per definir les propietats pròpies a la Taula, als TDs i als TRs, s'han de definir el el tag les propietats pròpies de les Taules, dels TDs i dels TRs: Les propietats referents al component taula es definiran amb el seu nom i el prefix 'grid'. Així, si volem definir la propietat 'style' de la taula, definirem la propietat gridStyle en el tag: gridStyle="border:1px solid black;" Les propietats referents als components de la taula (TD i TR) es definiran amb el seu nom habitual. Per especificar a quina o quines cel- les es vol aplicar la propietat, es farà de la següent manera: Si ens volem referir a una cel- la en concret, indicarem el número de fila i de columna que ocupa, separat pel caràcter ':'. Afegirem el valor de la propietat després el caràcter '=': style="2:1=border:1px solid black" Així, segons aquest exemple, la cel- la de la fila 2 columna 1 tindrà l'estil 'border:1px solid black'. Si volem definir una propietat per més d'una cel- la, ho farem separant les definicions amb el caràcter ',': style="2:1=border:1px solid black,2:2=background-color:blue" Si volem definir una propietat per tota una fila o tota una columna, ho farem mitjançant el caràcter '*': style="2:*=border:1px solid black " En l'exemple anterior, l'estil definit s'aplicarà a tota la fila 2. En aquest cas, però, s'aplicarà l'estil a totes les cel- les (TDs) de la fila, no a l'element fila (TR). Si volem aplicar la propietat al TR, ho farem mitjançant '**': style="2:**=border:1px solid black" En aquest cas, l'estil s'aplicarà al TR de la fila 2. Això només ho podrem fer amb les files, ja que compten amb l'element TR. Per les columnes, només podrem aplicar '*', i l'estil s'aplicarà a tots els TDs de la columna individualment. També podem definir alguna propietat per totes les cel- les de la taula mitjançant ':': style=":=background-color:blue" En aquest exemple s'aplica l'estil a tots els TDs de la taula. Si volem fer-ho amb tots els TRs, ho farem mitjançant ':*': style=":*=background-color:blue" La següent taula recull el diferents valors que hem definit per referir-nos a les cel.les:
A més de les propietats pròpies a les Taules,TDs i TRs s'han incorporat les següents propietats:
El contingut de cada cel- la del grid el definirem en el cos del Tag GridBadLayout. Cada node que trobem serà el contingut de cada cel- la, tenint en compte l'ordre en que els anem trobant. Si volem que una cel- la contingui més d'un element, els haurem d'agrupar algun altre element (com, per exemple, un 'div' o un 'span'), ja que el tag parssejarà el seu contingut com si es tractés d'un document XML, posant en cada cel- la del grid el contingut de cada node de primer nivell:
<fwk:gridBagLayout size="1,3" gridBorder="1" gridStyle="border:1px solid black;" colspan="1:1=2" rowspan="1:1=2"> <span><input type="text" name="text1" id="text1" value="text1"/></span> <input type="text" name="gridText" id="gridText"/> <span><input type="text" name="gridT" id="gridT" value="gridT"/></span> </fwk:gridBagLayout> En l'exemple anterior, es crearà una taula amb una fila i 3 columnes. En la primera cel- la hi posarà el contingut del primer node del cos del tag: <span><input type="text" name="text1" id="text1" value="text1"/></span> En la segona hi posarà el segon node: <input type="text" name="gridText" id="gridText"/> I, finalment, en la tercera, hi posarà el tercer i últim node: <span><input type="text" name="gridT" id="gridT" value="gridT"/></span> - Errors de construcció del grid Si en el contingut del tag hi tenim més elements que cel- les hem definit en l'atribut 'size', el tag llançarà una excepció. Si, en canvi, hi ha més cel- les que elements, el tag crearà les cel- les restants buides. El tag suporta també les propietats 'colspan' i 'rowspan'. Aquestes propietats es defineixen quan una cel- la ha d'ocupar més una fila o d'una columna. Amb aquestes propietats es poden definir incongruències. En aquests casos, el tag llançarà excepcions. Aquestes incongruències poden ser: - Definir una propietat fora de límits: <fwk:gridBagLayout size="1,3" colspan="1:3=2"> ... En l'exemple anterior, definim la propietat 'colspan' de la tercera i última columna cel- la del grid amb valor 2. Això només podria ser si el grid tingués 4 columnes. Així, el tag llançarà una excepció indicant el motiu de l'error. - Definir una propietat d'una cel- la que està solapada per la propietat 'colspan' o 'rowspan' d'una altra cel- la:
<fwk:gridBagLayout size="1,3" colspan="1:1=2" style="1:2=border:1px solid black"> ... En l'exemple anterior definim la propietat 'style' de la cel- la 1:2, però aquesta cel- la està solapada per la propietat 'colspan' de la cel.la 1:1. Així, el tag llançarà una excepció indicant l'error. - Exemple complet de GridBagLayout
<fwk:gridBagLayout size="3,3" gridBorder="1" gridStyle="border:1px solid black;" colspan="1:1=2" rowspan="1:1=2" style=":=border:1px solid black;,*:0=background-color:blue" onmouseover=":*=this.className='selected';" onmouseout=":*=this.className='zebra0';"> <span><input type="text" name="span1" id="span1" value="span1"/></span> <input type="text" name="gridText" id="gridText"/> <span><input type="text" name="gridT" id="gridT" value=" gridT "/></span> <span><input type="text" name="span2" id="span2" value="span2"/></span> <input type="text" name="gridText" id="gridText" value="gridText"/> <span><input type="text" name="gridT" id="gridT" value="gridT"/></span> </fwk:gridBagLayout> Paginació de selectsEl pagedSelect permet a l'usuari mostrar una llista paginada de suggeriments pel valor que ha escrit. Aquest només mostra un camp en concret, que és el que és copia al camp de text. És molt útil per mostrar llistes suggeriments de molts elements, ja que té la paginació. Aquest pagedSelect és importat de la llibreria ajaxtags 1.1 i s'ha adaptat perquè cridi al servei de cerques del framework i mostri correctament el resultat. Entre el servidor i client viatja una cadena json. Dependències: ajaxtags-1.1.jar
Id del component gràfic. Serveix per poder aplicar estils al component i poder-lo configurar a partir d'un xml (action-servlet-xxx.xml).
Camp de la query que serà la clau de la option
Camp de la query que serà el valor de la option
Nom del component.
Valor que tindran els paràmetres
Nom dels paràmetres dins la query. En la query es fa referència a aquests noms mitjançant la nomenclatura: /~nomParametre: ... ~/ Aquest camp contindrà tots els paràmetres de la query separats per comes.
Nom de la query. Aquesta query estarà definida dins de "canigo-services-web -list.xml". Exemple: canigo-services-web-list.xml
<bean name="valueListHandler" class="net.mlw.vlh.DefaultValueListHandlerImpl"> <property name="config.adapters"> <map> <entry key="categoriesList"> <bean parent="baseHibernateAdapter"> <property name="hql"> <value> FROM net.gencat.ctti.canigo.samples.jpetstore.model.Category AS vo WHERE 1=1 /~descn: AND vo.descn LIKE \{descn\} ~/ /sortColumn: ORDER BY vo.[sortColumn] [sortDirection]/ </value> </property> </bean> </entry> </map> </property> </bean> JSP: <input type="text" name="depValue" value="Birds"/> <fwk: PagedSelect styleId="preferredCategory.id" selectedKey="id" selectedValue="name" property="preferredCategory.id" dependentFields="depValue" queryParameters="descn" optionsListName="categoriesList"/> Exemple amb un sol resultat: Exemple amb varis resultats (amb paginació): Format i limitació d'entrada de dadesAquest component permet controlar el format i la limitació de l'entrada de dades d'un camp d'un formulari. Aquest component el podem utilitzar de dues maneres: mitjançant un decorador (fwk:formatKeyStroke) o directament en la configuració del tag text del Framework (fwk:text). És molt habitual el seu ús en números de telèfon, targetes de crèdit, dates, etc. Dependències: masks.js
Màscara que volem aplicar a un camp d'un formulari. Depenent del tipus de màscara seguirem un patró o un altre.
Tipus de màscara. Pot ser de 3 tipus: - Text: màscara de text. x: lletra [a-z]. Qualsevol altre caràcter que aparegui a la màscara s'escriurà automàticament. Exemple: xxxx## -> hola22 - Date: màscara de data. d: dia [0-9]. Exemples: dd/mm/yyyy -> 24/05/1980 - Number: màscara numèrica. $: indica la moneda (apareix automàticament). Exemples: 0#####.## -> 000534.23 * Per defecte el tipus de màscara és "text".
Id del camp al qual volem aplicar la màscara. Només aplicable al decorador formatKeyStroke, ja que en el tag Text el camp al qual es vol aplicar la màscara és ell mateix. Exemple amb decorador (fwk:formatKeyStroke):
<fwk:text styleId="firstname" property="firstname"/> <fwk:formatKeyStroke source="firstname" mask="xxxx##"/> Exemple sense decorador (fwk:text): <fwk:text styleId="firstname" property="firstname" mask="xxxx##"/> Llistats editablesEls llistats editables es basen en el suport de les propietats indexades. Per poder donar aquest suport s'han construït un seguit de tags per tal que es pugui fer un gestió correcte d'aquesta informació. Introducció
Una propietat indexada és: <fwk:text styleId="city" property="direccions[0].ciutat" /> Aquest camp mostra de la llista de direccions del bean pare, la ciutat de la primera direcció. En la versió 1.0 canigo sap renderitzar aquesta propietat, però no sap construir aquesta llista de direccions en la baixada del submit dins el bean pare. El problema principal que hi ha per construir la col- lecció de direccions, és que ningú coneix quins objectes ha de tenir dins. Per poder informar a canigo d'aquesta tasca s'ha construït un tag anomenat DefinePropertyTag. Tota llista del bean que és vol materialitzar en la baixa és necessari que estigui definida amb aquest tag. Les col- leccions editables poden provenir de moltes fonts. Un cas típic es que en el load del bean del formulari es carreguin també seves col- leccions per després mostrar en pantalla. Un altra cas seria aquell on les col- leccions tenen molts elements. Aquí és molt aconsellable fer servir la ValueList ja que dona suport a la paginació, i navegació entre pàgines de manera amigable. La gran diferència amb el model primer, es que aquesta llista es carrega mitjançant una query definida en canigo-web-lists.xml. Per tal que els tags de propietats indexades es renderitzin correctament, s'ha de enganxar-li al bean del formulari la col- lecció que ha vingut de la valueList. Aquest enganxament es pot fer amb el SetListTag, on se li ha d'indicar quina és la propietat indexada del bean del form, i on és la llista ha afegir. El suport a llistats editables també ofereix el poder afegir, seleccionar i esborrar elements d'un llistat. Aquests pressuposen que el llistat està contingut dins una table de HTML. SetListTagEl tag SetListTag és un component que permet omplir els elements d'una llista del Bean d'un formulari amb els d'una llista que tenim guardada en qualsevol scope de la pàgina. Per exemple, si les dades provenen d'una valuelist, haurem d'omplir la llista del Form Bean amb la propietat 'list' de l'scope 'page':
<fwk:setList listProperty="accounts" scopeKey="list" scope="page"/> Aquest exemple mostra com agafar la llista provinent de la ValueList i l'afegeix a la propietat accounts del bean del formulari. Les propietats d'aquest tag són les següents:
Nom de la propietat indexada en el bean del formulari.
Nom de la clau que conté la llista a afegir al bean del formulari.
Aquesta propietat només accepta 3 possibles valors: DefinePropertyTagEl tag DefinePropertyTag serveix per informar a canigo quins tipus de classe conté la col.lecció definir la classe que tenen els objectes continguts en la llista del Form Bean. Això es fa per poder fer el 'binding' dels nous objectes que es creïn a l'editar el llistat amb el Form Bean. Les propietats d'aquest tag són les següents:
<fwk: DefineProperty listProperty="accounts" itemsClass="net.gencat.ctti.canigo.samples.
jpetstore.model.Account"/>
Aquest tag crearà dos inputs ocults amb el següent format: <input type="hidden" name="Metadata.nom_llista. itemsClass" value="classe_items_llista"/> <input type="hidden" name="Metadata.nom_llista. lastIndex" value="tamany_llista"/> Exemple: <input type="hidden" name="_Metadata.accounts.itemsClass_" value="net.canigo.samples.model.Account"/> <input type="hidden" name="_Metadata.accounts.lastIndex_" value="2"/> SelectionTagEl tag SelectionTag serveix per seleccionar i deseleccionar tots els elements d'un llistat editable. Les propietats d'aquest tag són les següents:
Aquesta propietat defineix el camp del Form Bean que indicarà si el registre al qual pertany està seleccionat. El camp ha de ser un valor booleà i es representarà amb un element 'checkbox'.
Aquesta propietat defineix l'id de l'element al qual s'hi s'assignarà l'event 'onclick' que dispararà la funció de seleccionar o deseleccionar tots els 'checkbox' de la taula.
Els llistats editables es faràn sobre taules. La taula que contingui els registres haurà de tenir un id. Aquest id és el que hem d'indicar en la propietat 'target'.
Acció que s'ha d'executar. Els possibles valors són: Un exemple de la seva utilització podria ésser el següent:
<fwk:selection source="selectionButton" target="taulaId" listName="accounts" selectionProperty="selected" action="selectAll"/> <fwk:selection source="unselectionButton" target="taulaId" listName="accounts" selectionProperty="selected" action="unselectAll"/> En l'exemple anterior s'assigna a 2 botons (selectionButton i unselectionButton) les funcions de seleccionar i deseleccionar tots els registres de la taula (amb id 'taulaId') respectivament. DeleteRowsTagEl tag DeleteRowsTag serveix per eliminar els elements seleccionats d'un llistat editable. Les propietats d'aquest tag són les següents:
Aquesta propietat defineix el camp del Form Bean que indicarà si el registre al qual pertany està seleccionat. El camp ha de ser un valor booleà i es representarà amb un element 'checkbox'. Tots els 'checkbox' seleccionats indicaran els registres a esborrar.
Aquesta propietat defineix l'id de l'element al qual s'hi s'assignarà l'event 'onclick' que dispararà la funció de esborrar tots els registres seleccionats.
Id de la taula on s'esborraran els registres. Exemple:
<fwk: Deleterows source="deleteRowsButton" target="taulaId" listName="accounts" selectionProperty="selected"/> En l'exemple anterior s'assigna al botó amb id 'deleteRowsButton' la funció d'eliminar tots els registres seleccionats de la taula. AddRowTagEl tag AddRowTag serveix per afegir nous registres a un llistat editable. Funcionament Aquest fa una única petició a servidor d'obtenir la plantilla de fila nova. En aquesta es podran posar en els camps el valors per defecte de cada camp. Aquesta petició es fa amb el reqCode addRowEditList. Si l'action hereta del DispatchActionSuport en té un de genèric. Aquest construeix el bean pare buit amb la col.lecció indexada amb un element buit, i llavors fa el forward indicat per a que es construeixi la plantilla de fila nova. Aquest mètode es pot redefinit per tal que es creï un element dins la col- lecció amb els valors per defecte desitjats. La plantilla de fila nova té unes característiques especials. Les propietats indexades han de fer referència a l'element 0 de la col- lecció. Això és causa ja que canigo abans de renderitzar la plana omple la col- lecció amb un bean buit. Si és fes referència a un element superior a 0 en la plantilla sortirà una excepció. La variable {rowIndex} es reemplaça just en el pintat per la posició que ocupar en la llista indexada del bean. És molt útil per poder fer referència a component dins la mateixa fila, com és el cas de les validacions. Per tal que els components caixes de text es pintin és necessita que estiguin dins un formulari. I aquest tingui dins un table amb un tr, que és el que es pintarà com a plantilla de fila nova. Per tal que les validacions obligatòries de submit funcionin, es necessita que aquest formulari tingui el mateix identificador intern que el que conté el llistat editable. Per fer això s'ha d'afegir al formulari de la plantilla nova el següent:
generateId="<%=request.getParameter("formIdent")%>" Un cop el navegador té la plantilla de fila nova del servidor, a cada petició d'afegir fila nova el que fa és copia aquesta plantilla i li reemplaça la propietat indexada amb el valor 0 pel que li correspon en aquell moment en el llistat editable. Propietats del tag Les propietats d'aquest tag són les següents:
Aquesta propietat defineix l'id de l'element al qual s'assignarà l'event 'onclick' que dispararà la funció d'afegir un nou registre.
Id de la taula on es crearan els nous registres.
Posició gràfica de la taula on afegirem les noves plantilles. Els possibles valors poden ser:
Índex de la propietat indexada a partir del qual s'aniran renombrant les noves files. Lo més habitual és que l'startIndex sigui el nombre d'elements de lllista. Com que normalment no es sap s'ha d'emprar un variable que faci de comptador dins el jsp. url Els nous registres(o TRs) que s'han d'afegir a la taula es crearan a partir una plantilla. Aquesta plantilla serà una jsp on les propietats indexades sempre tindran index 0. El tag ja s'encarregarà de substituir el 0 per l'índex apropiat. La propietat 'url' indica la Action on es troba aquesta jsp, que contindrà una taula amb el TR que vulguem definir i que haurà de tenir la mateixa estructura que tots els altres registres (o TRs) de la taula. <table> <tr onmouseover="this.className='selected';" onmouseout="this.className='zebra0';"> <td> <input type="checkbox" name="accounts[0].selected"/> </td> <td> <input type="text" name="accounts[0].lastname"/> </td> </tr> </table> En l'exemple anterior definim una taula que conté la plantilla dels nous registres. Si en el tag hem informat la propietat 'startIndex' amb el valor 2, en afegir un nou registre el tag substituirà 'accounts[0]' per 'accounts[2]'; si n'afegim un altre, ho farà per 'accounts[3]', etc..
Nom de la funció dins la Action definida en 'url' que gestionarà l'enviament de la plantilla jsp.
Nom del forward que envia la plantilla jsp. Per defecte serà 'success'. Exemple:
<fwk:addrow url="/canigo-samples-jPetstore/AppJava/accounts.do" target="taulaId" source="triggerButton" listName="accounts" startIndex="$\{count\}" insertInRow="penultimate" reqCode="addRowEditList"/> En l'exemple anterior s'assigna al botó amb id 'triggerButton' la funció d'afegir els nous registres de la taula. Exemple complet de llistat editable amb valuelist:
<%@ include file="/WEB-INF/jsp/includes/fwkTagLibs.jsp" %> <br> <script src="/canigo-samples-jPetstore/scripts/ajax/ajaxtags/canigo-ajaxtags-editList.js" type="text/javascript"></script> <script src="/canigo-samples-jPetstore/scripts/ajax/json/json.js" type="text/javascript"></script> <c:set var="count" value="0"/> <fwk:vlhroot value="list" url="accounts.do?" includeParameters="reqCode" configName="vlConfig"> <fwk:form styleId="actionForm" action="accounts.do" reqCode="search"> <fwk:setList listProperty="accounts" scopeKey="list" scope="page"/> <fwk: DefineProperty listProperty="accounts" itemsClass="net.gencat.ctti.canigo.samples.jpetstore. model.Account"/> <table width="450" align="center" border="0"> <!-- pagination section --> <tr> <td align="left" nowrap="true"><c:out value="$\{list.valueListInfo.totalNumberOfEntries\}" /> <fmt:message key="jsp.accounts.accountList. total"/> - <fmt:message key="jsp.accounts.accountList.page"/> (<c:out value="$\{list.valueListInfo.pagingPage\}" /> <fmt:message key="jsp.accounts.accountList.of"/> <c:out value="$\{list.valueListInfo.totalNumberOfPages\}" />)</td> <td ><table border="0" align="right"><tr><td><fwk:vlhpaging /></td></table></td> </tr> <!-- end of Pagination --> <tr> <td colspan="2"> <table width="100%" class="classicLook" cellspacing="0" cellpadding="0" id="taulaId"> <tbody> <% String displayProvider = (request.getAttribute("displayProvider")!=null)?request. getAttribute("displayProvider").toString():""; %> <fwk:vlhrow bean="account" display="<%=displayProvider%>"> <vlh:attribute name="onmouseover">this.className='selected';</vlh:attribute> <vlh:attribute name="onmouseout">this.className='zebra0';</vlh:attribute> <fwk:vlhcolumn titleKey="jsp.accounts.accountList.lastname" property="lastname"> <fwk:checkbox property="accounts[$\{count\}].selected" styleId="accounts[$\{count\}].selected" layout="false"/> </fwk:vlhcolumn> <fwk:vlhcolumn titleKey="jsp.accounts.accountList.id" property="id"> <fwk:vlhaction url="editAccount.do?"> <fwk:vlhaddParam name="reqCode" value="edit" temp="false" /> <fwk:vlhaddParam name="id" property="id" temp="false" /> <c:out value="$\{account.id\}"></c:out> </fwk:vlhaction> </fwk:vlhcolumn> <fwk:vlhcolumn titleKey="jsp.accounts.accountList.firstname" property="firstname"/> <fwk:vlhcolumn titleKey="jsp.accounts.accountList.lastname" property="lastname"> <fwk:text property="accounts[$\{count\}].lastname" styleId="accounts[$\{count\}].lastname" layout="false"/> </fwk:vlhcolumn> <fwk:vlhcolumn titleKey="forms.accountForm.field.preferredCategory" property="preferredCategory.id"> <fwk:select styleId="preferredCategory.id" property="preferredCategory.id"/> </fwk:vlhcolumn> <c:set var="count" value="$\{count + 1\}"/> </fwk:vlhrow> <tr> <td colspan="4" style="text-align:right"> <table align="right"><tr><td style="border: 0px"><fmt:message key="jsp.common.export"/> </td> <td style="border: 0px"><html:link page="/accounts.do?reqCode=searchExportPDF" target="_blank"> <img src="<%=request.getContextPath()%>/images/icono_acrobat.gif" border="0"/></html:link></td> <td style="border: 0px"><html:link page="/accounts.do?reqCode=searchExportExcel" target="_blank"> <img src="<%=request.getContextPath()%>/images/icono_excel.gif" border="0"/></html:link></td> </td> </tr> </tbody> </table> </td> </tr> </table> <input type="button" name="triggerButton" id="triggerButton" value="Add Row"/> <input type="button" name="selectionButton" id="selectionButton" value="Select All"/> <input type="button" name="unselectionButton" id="unselectionButton" value="Unselect All"/> <input type="button" name="deleteRowsButton" id="deleteRowsButton" value="Delete selecteds"/> <br> <fwk:selection source="selectionButton" target="taulaId" listName="accounts" selectionProperty="selected" action="selectAll"/> <fwk:selection source="unselectionButton" target="taulaId" listName="accounts" selectionProperty="selected" action="unselectAll"/> <fwk: Deleterows source="deleteRowsButton" target="taulaId" listName="accounts" selectionProperty="selected"/> <fwk:addrow url="/canigo-samples-jPetstore/AppJava/accounts.do" target="taulaId" source="triggerButton" listName="accounts" startIndex="$\{count\}" insertInRow="penultimate" reqCode="addRowEditList"/> <fwk:submit value="submit" styleId="submit" reqCode="save"/> </fwk:form> </fwk:vlhroot> ![]() Servei de validacions en el jspEl dividirem en dos gran àrees. La primera serà el motor de regles, i la segona el servei de presentació de missatges d'error. Motor de reglesEl motor de regles és el conjunt de mètodes que permeten validar si les dades són correctes. Definició de reglesPer definir les regles de validació és fa servir el framework commons-validator 1.3.0 d'Apache. <validator name="maxlength" classname="org.springmodules.validation.commons.FieldChecks" method="validateMaxLength" methodParams="java.lang.Object, org.apache.commons.validator.ValidatorAction, org.apache.commons.validator.Field, org.springframework.validation.Errors" depends="" msg="errors.maxlength"> <javascript><![CDATA[ function validateMaxLength(form) { var isValid = true; var focusField = null; var i = 0; var fields = new Array(); oMaxLength = new maxlength(); for (x in oMaxLength) { var field = form[oMaxLength[x][0]]; // canigo modification. Added if. In some cases, a 'extend' // field appears that is not a field. if (field) { if (field.type == 'text' || field.type == 'textarea') { var iMax = parseInt(oMaxLength[x][2]("maxlength")); if (field.value.length > iMax) { if (i == 0) { focusField = field; } fields[i++] = oMaxLength[x][1]; isValid = false; } } } } if (fields.length > 0) { focusField.focus(); alert(fields.join('\n')); } return isValid; }]]> </javascript> </validator> Les regles que tenen definida la funció javascript permeten l'execució en client, però sempre han de tenir la implementació en java per garantir l'execució en servidor. Les regles poden dependre d'un o més camps. Aquelles que necessiten més d'un camps per validar en direm que són regles amb camps dependents. Per tant se li ha d'indicar d'alguna manera aquesta necessitat. Amb el commons-validator és fa mitjançant passant-li els valors dels camps com argument, en canvi amb el nou tag de validacions s'indica amb un atribut a mida. Events de validacióEls events que llencen el sistema de validació són els següents: - onSubmit del formulari: Quan es fa un submit del formulari és llença una petició de validació via AJAX cap a servidor o s' executa regles de javascipt si es validació client . Si aquesta és correcta es fa el submit. Per qüestions de seguretat, quan es fa el submit en servidor es torna a validar les dades que són les que entraran a l'action. Per exemple si es desactivés el javascript les validacions AJAX no funcionarien, però al baixar les dades és validaran per les validacions obligatòries de submit. Aquestes validacions de submit obligatòries són configurables i pots establir quin mètodes han de tenir validacions obligatòries.
<bean name="/accountList" parent="accountListBaseDefinition"> <property name="webValidationSubmit" ref="webValidationSubmit"/> <property name="metodosList"> <list> <value>save</value> </list> </property> </bean> En l''action accountList s'ha definit que hi ha validacions obligatòries de submit pel mètode save de l'action. Les regles a executar per un formulari és defineixen en el validation.xml
<form name="accountList"> <field property="firstname" depends="required"> <arg0 key="forms.accountForm.field.firstname"/> </field> <field property="lastname" depends="required"> <arg0 key="forms.accountForm.field.firstname"/> </field> </form> El conjunt de regles anomenades accountList obliguen ha tenir el camp firstname i lastname informats. Altrament aquesta seria la manera antiga. Amb la nova versió és permet definir les validacions de submit d'un camp en el mateix tag del jsp. Aquesta manera és més flexible i es poden veure fàcilment les validacions d'una pàgina. Un exemple és :
<fwk:text styleId="firstname" styleClass="fieldtext" property="firstname" validations="ONSUBMIT(required)" /> <fwk:text styleId="lastname" styleClass="fieldtext" property="lastname" validations="ONSUBMIT(required)"/> Aquest exemple és sinònim de l'anterior. A l'atribut validations es posa ONSUBMIT( < regla de validació >, < regla de validació > ..) on les regles de validacions han d'estar definides en el validation-rules.xml. - onChange d'un camp de text: Aquest event permet validar el contingut d'un camp un cop ha canviat. Són el que s'anomenen les validacions de camp. Aquestes validacions només permeten execució de regles en servidor, mitjançant petició AJAX. La manera d'expressar aquestes validacions és:
<fwk:text styleId="lastname" styleClass="fieldtext" property="lastname" validationFieldMessageMode="ICON,TEXTERROR" validations="ONCHANGE(required) " errorClass="errorNew" errorKey="forms.accountForm.field.lastname" iconStyleId="lastnameIconError" textErrorStyleId="lastnameTextError" /> Escrivint ONCHANGE(..<regla de validació>, <regla de validació>) en l'atribut validations és defineix les validacions camp a camp. Aquestes regles de validació han d'estar definides en el fitxer validation-rules.xml. Les regles de validació poden tenir un o més paràmetres. La forma d'indicar-los és posar els paràmetres dins de la notació {} i separats per punt i coma:
<fwk:text styleId="birthdate" styleClass="fieldtext" property=" birthdate " validationFieldMessageMode="ICON,TEXTERROR" validations="ONCHANGE(required, date\{datePattern: Dd/MM/yyyy;dateLength:10\})" errorClass="errorNew" errorKey="forms.accountForm.field.lastname" iconStyleId="lastnameIconError" textErrorStyleId="lastnameTextError" /> Els altres atributs serveixen per mostrar l'avís d'error que seguidament s'explicarà en el següent apartat. Presentació de missatgesPrincipalment són quatre tags, dos per validacions camp a camp i els altres dos per validacions de formulari. Form i FormValidatorEl FormValidator és un decorador que permet associar a un formulari validacions. Els atributs dels dos són bastant semblants per tant s'explicaran junts. fwk:Form: Només s'exposen atributs de validació.
fwk:FormValidator:
Indica les maneres de mostrar els errors de formulari. Hi ha 3 maneres possibles. Es poden combinar els tres elements, encara que PANEL i WINDOW poden semblar contradictori, com per exemple PANEL,FIELDS;WINDOW o PANEL,FIELDS.
Funció javascript que s'encarrega de fer la presentació del errors. Aquest és pels usuaris que volguessin fer un presentació d'errors a mida.
Div que es mostra mentre s'està fent petició a servidor via AJAX.
Aquest atribut és necessari per quan no estant configurades les validacions del commons validator i només hi ha validacions dels tags. El seu valor pot ser CLIENT o SERVER, i indica on s'executaran les validacions. Si l'atribut mode i el validationType no fossin iguals saltarà una excepció avisant del conflicte.
Identificador del panell incrustat. Si no s'identifica fa servir el per defecte. Text i FieldValidatorfwk:text: Només es mostren els atributs referents a validacions.
fwk:fieldValidator*: permet que a qualsevol camp de text se li puguin associar validacions
Cadena que indica les validacions d'un camp. La cadena permesa és: r1,r2,r3,r4 han d'estar definides en el validation-rules.xml.
Els valors permesos és un combinació separada per comes dels següents valors. TOOLTIP: És mostra un tooltip amb el missatge d'error en el camp o en l' icona. Per exemple, si fos TOOLTIP, ICON, mostra un tooltip i una icona.
Indica on és vol mostrar el tooltip. Els valors possibles són dos:
Identificador del div que conté l' icona. El tag iconError és un tag fet a mida per mostrar icones.
Identificador del div que mostra el missatge d'error incrustat. El tag textError ajuda en aquesta tasca.
Nom de classe CSS que s'aplica en cas d'error en el camp. Normalment posa el marc en vermell del camp i canvia el color de fons.
Funció javascript que permet la presentació del missatge d'error a mida.
Llista de camps dependents. Per exemple pot ser:
<fwk:text property="age" dependentFields="currentDate,birdhDate" /> L'atribut dependentFields està composat d'identificadors (styleId) de diferents camps del formulari.
Argument que es s'envia per construir el missatge d'error. Suposem errorKey = ' ciutat' Si hi ha les validacions activades aquest camp es obligatori.
Identificador del div que es mostra quan hi ha petició a servidor. IconError i TextErrorAquests dos tags són d'ajuda per tal de facilitar la mostra d'errors del sistema de validació. L'IconError s'encarrega d'encapsular la imatge d'avís d'error.
Exemple El TextError és un div que permet afegir-hi el missatge d'error.
Exemples: - ICON & TEXTERROR
<td><fwk:text styleId="lastname" styleClass="fieldtext" property="lastname" validationFieldMessageMode="ICON,TEXTERROR" validations="ONCHANGE(required),ONSUBMIT(required)" sourceErrorTooltip="TEXT" dependentFields="firstname" errorClass="errorNew" errorKey="forms.accountForm.field.lastname" iconStyleId="lastnameIconError" textErrorStyleId="lastnameTextError" /></td> <td><fwk:iconError styleId="lastnameIconError" style="display:none" styleClass="iconError"> <img src="<c:url value="/images/iconWarning.gif"/>" id="imagen" class="icon" /> </fwk:iconError></td> <td><fwk:textError styleId="lastnameTextError" styleClass="errorText" /></td> ![]() - ICON, TOOLTIP & CHANGESTYLE
<td><fwk:text styleId="state" property="state" styleClass="fieldtext" validationFieldMessageMode="ICON,TOOLTIP,CHANGESTYLE" validations="ONCHANGE(required),ONSUBMIT(required)" sourceErrorTooltip="TEXT" dependentFields="firstname" errorClass="errorNew" errorKey="forms.accountForm.field.state" iconStyleId="stateIconError" textErrorStyleId="stateTextError" /> </td> <td><fwk:iconError styleId="stateIconError" style="display:none" styleClass="iconError"> <img src="<c:url value="/images/iconWarning.gif"/>" id="imagen" class="icon" /> </fwk:iconError></td> <td><fwk:textError styleId="stateTextError" styleClass="errorText" /> </td> ![]() Validacions en llistats editablesLes validacions en llistats editables és el suport a propietats indexades. És a dir poder validar camps amb els noms de propietats a[1].id o a.b[2].name,etc. Els [] denoten propietats indexades i són pròpies de llistats editables. Seguidament és mostra un exemple de validació en propietats indexades.
<fwk:text styleId="city" property="accounts[0].city" size="20" validationFieldMessageMode="ICON,TOOLTIP,CHANGESTYLE" validations="ONCHANGE(required), ONSUBMIT(required)" sourceErrorTooltip="TEXT" iconStyleId="iconErrorCity$\{count\}" errorKey="forms.accountForm.field.city" errorClass="errorNew"/> Seguidament s'explicarà les peculiaritats segons el mètode de validació. -onChange: Per aquest sistema no hi ha absolutament cap problema ja que el camp és un etiqueta per aquest sistema de validació i li és igual com s'escrigui. -onSubmit per commons validator: No s'aconsella pel motius seguidament explicats. Les propietats indexades s'han d'especificar amb l'atribut indexedListProperty i s'ha d'especificar el nom de la propietat que és una llista.
<form name="accountList"> <field property="firstname" indexedListProperty="accounts" depends="required"> <arg0 key="forms.accountForm.field.firstname"/> </field> <field property="lastname" indexedListProperty="accounts" depends="required"> <arg0 key="forms.accountForm.field.firstname"/> </field> </form> El problema d'aquest sistema és que el sistema de presentació d'errors rep el camp erroni però no s'indica la fila errònia i per tant no es pot saber quin camp està malament. Per exemple en el cas anterior, es rebria com error accounts[].city. -onSubmit per tags. Si es defineix l'event onSubmit en els tags el problema sorgeix en el mecanisme d'afegir files noves. Aquest mecanisme dispara un única petició a servidor en busca de la plantilla nova d' afegir. Un cop la té el navegador reemplaça el nomCollecció[0], pel número nomColecció[ultimIndex]. El problema d'aquest mecanisme es que les validacions de submit s'associen a un identificador intern de formulari i es queden a sessió, i per tant per les noves files no hi ha associades validacions de submit.
Això és fa amb el tag validateCollection.
Exemple:
<fwk:validateCollection property="accounts" indexReference="0"/> Si en la plantilla de files noves (addRow.jsp) és tenen tags del fwk, segurament caldrà un formulari. En el cas de definir validacions de submit en aquesta plantilla, s'haurà d'informar en el formulari l'atribut generateId.
<fwk:form styleId="actionForm11" action="accountList.do" reqCode="save" generateId="<%=request.getParameter("formIdent")%>" services="logService:loggingService" > Utilització del ServeiÚs dels tags a les pàgines JSPL'ús de cadascun dels tags implica 2 passos:
Des de la versió JSP 1.2 no és necessari configurar al fitxer web.xml la llibreria i podem fer referències directes mitjançant url al jar, tal i com es mostra a continuació:
<%@ taglib prefix="fwk" uri="http://www.ctti.net/canigo/open-layout" %>
Una vegada definida la referència a la llibreria i el seu prefix 'fwk' podem incorporar qualsevol tag mitjançant '<fwk:nomTag>'. Per tots els tags d'entrada de dades de formulari es definiran els atributs:
Exemple:
<fwk:text styleId="firstname" property="firstname"/> En la següent taula es dona un resum dels tags permesos i la correspondència amb la seva classe que s'ha de definir en el fitxer de configuració:
Comentaris Específics a alguns TagsEn l'ús del tag 'select' es recomana l'ús de JSTL per a la generació de les opcions incloses. Exemple:
<fkw:select styleId="..." property="..."> <c:forEach items="$\{nombreLista\}" var="item"> <fwk:option value="$\{item\}">$\{item.descripcion\}</fwk:option> </c:forEach> </select> Especificació del Mode del FormulariEn la configuració dels components d'entrada de formulari s'ha explicat com podem mostrar-los de forma diferents segons el mode del formulari. Aquest mode de formulari pot canviar-se mitjançant la crida: FormUtils.setFormDisplayMode(request, actionForm,mode); On mode pot ser un dels següents valors: - FormUtils.INSPECT_MODE. Mode de consulta NOTA: public static final String EDIT_METHOD_PREFIX = "edit";
Eines de SuportDebug de les PàginesEn l'ús de les nostres pàgines és convenient sempre conèixer si estan ben construïdes. Tal i com es comenta al document 'Entorn de Desenvolupament' mitjançant l'extensió 'Web Developer' i 'Javascript Debugger' podem esbrinar i detectar problemàtiques de les nostres pàgines. AnnexosJSTLDes de fa un temps existeix JSTL (JSP Standard Tag Library). Aquesta llibreria de tags defineix algunes de les tasques bàsiques que necessitem a les nostres pàgines JSP (condicionals, presentació de valors, internacionalització, ...). Si bé no ofereix totes les necessitats que requerim d'una aplicació Web sí ofereix la base del que prèviament es feia amb codi Java o els tags de Struts. Es recomana l'ús dels tags JSTL de 'core' i 'fmt' que es poden referenciar dins les nostres pàgines com:
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %> Podeu veure un resum de JSTL a la url 'http://www.1x4x9.info/files/jstl/html/online-chunked'. Altres TagsTot i l'oferta de tags de canigo, existeixen altres necessitats, com per exemple l'ús de pestanyes. En aquest apartat s'ofereixen una llista de components disponibles a la comunitat que poden resoldre aquestes necessitats:
Per a mostrar el típic tag d'enllaços a on ens trobem dins la pàgina podem usar el tag de Crumbs de 'Struts Layout'. Consultar 'http://struts.application-servers.com/doc/tags/crumbs.html' per conèixer la seva utilització.
Per a utilitzar pestanyes es recomana la utilització del tag de 'Ditchnet'3 Aspectes d'UsabilitatAquesta secció pretén donar una visió general del quins aspectes s'han tingut en consideració en els components canigo per a complir amb normes bàsiques d'usabilitat i accessibilitat. Algunes de les guies proporcionades poden resultar òbvies però considerem la necessitat de fer-les esmentar per a tenir en consideració. En qualsevol cas, moltes de les guies explicades es troben implementades per canigo en els seus tags, pel que no s'hauran de tenir en consideració per al desenvolupament de les aplicacions Web. Si més no, també és el nostre propósit mostrar per què s'han pres determinades decisions basades en les guies aquí establertes. A continuació es detallen les guies utilitzades:
(1) i (2) són realitzats pels tags canigo.
canigo permet especificar la propietat 'selectOnFocus' per a lligar aquest comportament als nostres components. Per defecte es troba a 'true'.
Aquestes propietats han de ser definides pels desenvolupadors.
canigo mostra, per defecte, un asterisc a l'esquerra de l'etiqueta del component si el seu atribut associat ha estat definit com a obligatori dins el Servei de Validació.
Per exemple podem usar el següent estil (basat en 'theserverside.com'):
form input, form textarea, form select { padding-left: 4px; color: #666; } O bé: input.input-text, textarea { border: 1px solid #859085; background: transparent; padding: 1px 3px; } input.hover, textarea.hover { border-color: #000; background-color: #ffe; } input.active, textarea.active { border-color: #f00; background-color: #fff; } input.input-button, button, select { border-width: 1px; padding: 0px; } input.input-text, input.input-button, button, select, textarea { font: 90% tahoma,verdana,sans-serif; } input.input-disabled { background-color: #ccc; border-color: #999; color: #777; } CSS (Cascade Style Sheets)Tot i que no és propòsit de canigo oferir un tutorial en detall de què són els CSS i com fer-los servir es considera bàsic el seu coneixement. A continuació s'ofereix un resum de quins aspectes es consideren important a tenir en compte: Importació de fitxers d'estilsPodem agrupar l'ús de varis fitxers d'estils mitjançant la sentència '@import'.
<style type="text/css" media="all"> @import "file1.css"; @import "file2.css"; </style> Utilització de ids i classesMitjançant l'ús d'identificadors de classe (incorporant '.' al davant del nom de la classe) podem definir quin serà l'estil a aplicar a tots els tags que incorporin aquest nom de class (en els tags canigo correspon a la propietat 'styleClass').
.required \{font-family: Verdana; font-size: 12pt; color: red; \} Aquest estil s'aplicarà a tots els components que tinguin com a class='required', siguin divs, spans, ... En cas que volem aplicar un estil a un únic component farem servir identificadors. És a dir, partint del id assignat al component (en canigo l'atribut 'styleId' dels components), podem assignar un estil usant '#':
#header \{width: 90%; background: white; font-size: 20px; color: purple; \} <div id="header">...</div>
Sempre podem definir els estils al mateix component (atribut 'style') o sobreescriure els definits al fitxer d'estil: <span class="caution" style="color: green">text</span> Si volem definir el mateix estil a diferents ids o classes podem separar cadascun d'ells amb espai tal i com es mostra en el següent exemple: p b \{color: red; \} Inclús podem definir que tots els components inclosos a un id o class determinat actuïn de forma determinada: div#navigation a \{color: white; \} En aquest cas, s'aplicarà l'estil a tots els '<a href...' que estiguin inclosos a un div amb id='navigation' Efectes ComunsEn la següent taula es mostra un resum d'algunes de les propietats més útils a definir:
Pseudo ClassesTot i que podem definir selectors o estils a la majoria d'elements, hi ha parts que no són elements en sí sinó parts d'aquests. Mitjançant pseudo classes podem accedir a aquests elements. Com a guia de canigo es proporciona al fitxer d'estils una pseudo classe per presentar els components d'entrada de diferent forma quan ubiquem el focus.
form input, form textarea, form select { padding-left: 4px; color: #666; } /* Warning: IE doesn't support pseudo-class :focus */ form input:focus, form textarea:focus, form select:focus { border-bottom: #ffdead solid 2px; border-right: #ffdead solid 2px; border-left: #c07300 solid 2px; border-top: #c07300 solid 2px; color: #000; } NOTA: Internet Explorer no suporta pseudo classes Podeu veure una introducció a 'http://www.adaptivepath.com/publications/essays/archives/000385.php' http://209.61.157.8:8080/taglibs/ |